package com.ecoolex.chinadutyfree.retailer.core.manager;

import java.time.Instant;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ecoolex.chinadutyfree.retailer.core.dao.DirectMailGoodsDAO;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoods;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoods.Column;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsExample;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsExample.Criteria;
import com.ecoolex.chinadutyfree.retailer.entity.FreightTemplate;
import com.ecoolex.chinadutyfree.retailer.enums.DirectMailGoodsProductStatus;
import com.ecoolex.chinadutyfree.retailer.enums.DirectMailGoodsStatus;
import com.ecoolex.chinadutyfree.retailer.pojo.QueryDirectMailGoodsDTO;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.exception.BizException;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;


@Service
public class DirectMailGoodsManager {

    @Autowired
    private DirectMailGoodsDAO dao;

    @Autowired
    private DirectMailGoodsDeliveryMannerManager directMailGoodsDeliveryMannerManager;

    @Autowired
    private DirectMailGoodsDummyManager directMailGoodsDummyManager;

    @Autowired
    private DirectMailGoodsProductManager directMailGoodsProductManager;

    @Autowired
    private GoodsManager goodsManager;

    @Autowired
    private FreightTemplateManager freightTemplateManager;

    @Autowired
    private DirectMailGoodsShoppingCartManager directMailGoodsShoppingCartManager;
    
    @Autowired
    private DirectMailGoodsAuditManager directMailGoodsAuditManager;

    public long countByFreightTemplateId(Integer freightTemplateId) {
        DirectMailGoodsExample example = new DirectMailGoodsExample();
        example.createCriteria().andFreightTemplateIdEqualTo(freightTemplateId).andDeletedEqualTo(
                DirectMailGoods.NOT_DELETED);
        return dao.countByExample(example);
    }

    public long countByGoodsId(Integer goodsId) {
        DirectMailGoodsExample example = new DirectMailGoodsExample();
        example.createCriteria().andGoodsIdEqualTo(goodsId).andDeletedEqualTo(DirectMailGoods.NOT_DELETED);
        return dao.countByExample(example);
    }

    private void verify(DirectMailGoods record, List<Integer> deliveryMannerList) {
        BizAssert.isTrue(Check.notNull(goodsManager.getById(record.getGoodsId())),
                ResultCode.VERIFY.build(10),
                "商品不存在");
        BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getCurrencyType()), ResultCode.VERIFY.build(11), "币种为空");
        // 运费模板
        BizAssert.isTrue(Check.notNull(record.getFreightTemplateId()), ResultCode.VERIFY.build(12), "运费模板为空");
        FreightTemplate freightTemplate = freightTemplateManager.getById(record.getFreightTemplateId());
        BizAssert.isTrue(Check.notNull(freightTemplate), ResultCode.VERIFY.build(13), "运费模板不存在");
        BizAssert.isTrue(Check.eq(record.getCurrencyType(), freightTemplate.getCurrencyType()),
                ResultCode.VERIFY.build(14),
                "币种与运费模板币种不一致");
//        2020-07-03 15:17:13 删除配置方式
//        BizAssert.isTrue(Check.notNullOrEmpty(deliveryMannerList), ResultCode.VERIFY.build(15), "配送方式为空");
    }

    @Transactional
    public DirectMailGoods add(DirectMailGoods record, List<Integer> deliveryMannerList, String createUser) {
        verify(record, deliveryMannerList);

        record.setStatus(DirectMailGoodsStatus.OFFLINE.real());
        record.setDeleted(DirectMailGoods.NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);
        // 配送方式
//        zhangdongjie (zhangdongjie@ecoolex.com) 2020-07-03 15:17:13 删除配送方式
//        directMailGoodsDeliveryMannerManager.update(record, deliveryMannerList, createUser);
        // 创建虚拟配置
        directMailGoodsDummyManager.create(record, createUser);
        return record;
    }

    @Transactional
    public DirectMailGoods update(DirectMailGoods record, List<Integer> deliveryMannerList, String updateUser) {
        verify(record, deliveryMannerList);
        //编辑后变成下线，需要重新提交上线审核
        record.setStatus(DirectMailGoodsStatus.OFFLINE.real());
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record,
                Column.excludes(Column.goodsId, Column.deleted, Column.createUser, Column.createTime));
        // 配送方式
        // zhangdongjie (zhangdongjie@ecoolex.com) 2020-07-03 15:17:13 删除配送方式
//        directMailGoodsDeliveryMannerManager.update(record, deliveryMannerList, updateUser);
        return record;
    }

    @Autowired
    private DirectMailGoodsMarketingManager directMailGoodsMarketingManager;

    @Transactional
    public void delete(DirectMailGoods record, String updateUser) {
        BizAssert.isTrue(DirectMailGoodsStatus.RELEASE.notEqual(record.getStatus()),
                ResultCode.VERIFY.build(10),
                "发布状态无法删除");

        long marketingNumber = directMailGoodsMarketingManager.countByDirectMailGoodsId(record.getDirectMailGoodsId());
        BizAssert.isTrue(marketingNumber == 0, ResultCode.VERIFY.build(11), "商品存在{}个营销配置, 无法删除", marketingNumber);

        record.setDeleted(DirectMailGoods.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record, Column.deleted, Column.updateUser, Column.updateTime);

        // 删除快递方式
        directMailGoodsDeliveryMannerManager.deleteByDirectMailGoodsId(record.getDirectMailGoodsId(), updateUser);
        // 删除虚拟配置
        directMailGoodsDummyManager.deleteByDirectMailGoodsId(record.getDirectMailGoodsId(), updateUser);
        // 删除产品
        directMailGoodsProductManager.deleteByDirectMailGoodsId(record.getDirectMailGoodsId(), updateUser);
    }

    @Transactional
    public DirectMailGoods offline(DirectMailGoods record, String updateUser) {
        // 检查是否是上线状态
        BizAssert.isTrue(DirectMailGoodsStatus.RELEASE.equal(record.getStatus()),
                ResultCode.VERIFY.build(10),
                "非发布状态无法下线");

        record.setStatus(DirectMailGoodsStatus.OFFLINE.real());
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record, Column.status, Column.updateUser, Column.updateTime);
        // 作废购物车内的商品
        directMailGoodsShoppingCartManager.invalidByDirectMailGoodsId(record.getDirectMailGoodsId(), updateUser);
        return record;
    }

    @Transactional
    public DirectMailGoods release(DirectMailGoods record, String updateUser) {
        BizAssert.isTrue(DirectMailGoodsStatus.RELEASE.notEqual(record.getStatus()) && DirectMailGoodsStatus.WAIT_AUDIT.notEqual(record.getStatus()),
                ResultCode.VERIFY.build(10),
                "发布状态无法再次发布");

        // 检查产品配置状态
        // 有效商品状态大于0
        long normalProductNumber = directMailGoodsProductManager.countByGoodsIdAndStatus(record.getDirectMailGoodsId(),
                DirectMailGoodsProductStatus.NORMAL);
        BizAssert.isTrue(normalProductNumber > 0, ResultCode.VERIFY.build(11), "没有正常状态产品,无法发布");

        record.setStatus(DirectMailGoodsStatus.WAIT_AUDIT.real());
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record, Column.status, Column.updateUser, Column.updateTime);

        return record;
    }
    
    @Transactional
    public DirectMailGoods agreeDirectMailGoodsRelease(DirectMailGoods record, String updateUser) throws BizException {
    	record.setStatus(DirectMailGoodsStatus.RELEASE.real());
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record, Column.status, Column.updateUser, Column.updateTime);
        //添加审核记录
        directMailGoodsAuditManager.create(record.getDirectMailGoodsId(), true, null, updateUser);
        return record;
	}

    @Transactional
	public DirectMailGoods refuseDirectMailGoodsRelease(DirectMailGoods record, String auditOpinion, String updateUser) throws BizException {
		record.setStatus(DirectMailGoodsStatus.OFFLINE.real());
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record, Column.status, Column.updateUser, Column.updateTime);
        //添加审核记录
        directMailGoodsAuditManager.create(record.getDirectMailGoodsId(), false, auditOpinion, updateUser);
        return record;
	}

    public DirectMailGoods getById(Integer directMailGoodsId) {
        return dao.selectByPrimaryKeyWithLogicalDelete(directMailGoodsId, DirectMailGoods.NOT_DELETED);
    }

    public Pagination<DirectMailGoods> query(QueryDirectMailGoodsDTO query, Sorting[] sorts, Page page) {
        //存在二级分类就必须有一级分类
        if (Check.notNullAndGtZero(query.getSecondaryCategoryId())) {
            BizAssert.isTrue(Check.notNullAndGtZero(query.getPrimaryCategoryId()), ResultCode.VERIFY.build(10), "缺少一级分类");
        }
        return Pagination.create(page,
                dao.count(query),
                () -> dao.query(query, Sortings.builder(sorts).verify(Column::valueOf).toSql(), page));
    }

    /**
     * 用户查询推荐直邮商品
     *
     * @return
     */
    public Pagination<DirectMailGoods> queryRecommendForH5(String position, String[] positionValue, Sorting[] sorts, Page page) {
        // TODO:排序字段校验
        return Pagination.create(page,
                dao.countByPosition(position, positionValue),
                () -> dao.queryByPosition(position, positionValue, Sortings.builder(sorts).toSql(), page));
    }

    /**
     * 用户查询直邮商品
     *
     * @return
     */
    public Pagination<DirectMailGoods> queryForH5(String customName, Sorting[] sorts, Page page) {
        DirectMailGoodsExample example = new DirectMailGoodsExample();
        DirectMailGoodsExample.Criteria criteria = example.createCriteria();

        if (Check.notNullOrTrimEmpty(customName)) {
            criteria.andCustomNameLike('%' + customName
                    + '%');
        }

        criteria.andStatusEqualTo(DirectMailGoodsStatus.RELEASE.real());
        criteria.andDeletedEqualTo(DirectMailGoods.NOT_DELETED);
        example.orderBy(Sortings.builder(sorts).toSql());
        example.setOffset(page.getFirstIndex());
        example.setRows(page.getPageSize());

        return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExample(example));
    }

    /**
     * 用户根据二级商品分类查询直邮商品列表
     *
     * @return
     */
    public Pagination<DirectMailGoods> queryByCategoryIdForH5(Integer categoryId, Sorting[] sorts, Page page) {

        return Pagination.create(page,
                dao.countByCategory(categoryId),
                () -> dao.queryByCategory(categoryId, Sortings.builder(sorts).toSql(), page));
    }

    /**
     * 查询一级分类下的商品
     *
     * @param categoryId
     * @param sorts
     * @param page
     *
     * @return
     */
    public Pagination<DirectMailGoods> queryByFirstCategoryIdForH5(Integer categoryId, Sorting[] sorts, Page page) {
        return Pagination.create(page,
                dao.countByFirstCategory(categoryId),
                () -> dao.queryByFirstCategory(categoryId, Sortings.builder(sorts).toSql(), page));
    }

    /**
     * 用户根据直邮商品id查询详情
     *
     * @param directMailGoodsId
     *
     * @return
     */
    public DirectMailGoods getByIdForH5(Integer directMailGoodsId) {
        DirectMailGoodsExample example = new DirectMailGoodsExample();
        Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(DirectMailGoods.NOT_DELETED);
        criteria.andStatusEqualTo(DirectMailGoodsStatus.RELEASE.real());
        criteria.andDirectMailGoodsIdEqualTo(directMailGoodsId);
        return dao.selectOneByExampleWithBLOBs(example);
    }

    public List<DirectMailGoods> getByGoodsId(Integer goodsId) {
        DirectMailGoodsExample example = new DirectMailGoodsExample();
        Criteria criteria = example.createCriteria();
        criteria.andGoodsIdEqualTo(goodsId).andDeletedEqualTo(DirectMailGoods.NOT_DELETED);
        return dao.selectByExample(example);
    }
    
    public Pagination<DirectMailGoods> queryByBrandId(String name,Sorting[] sorts,Integer brandId, Page page) {
    	return Pagination.create(page,
            dao.countByBrandId(name,brandId),
            () -> dao.queryByBrandId(name,Sortings.builder(sorts).toSql(),brandId, page));
	}
    
    public Long countDirectMailGoodsNumberByBrandId(Integer brandId) {
		return dao.countByBrandId(null,brandId);
	}
}